// http.ts
import axios, {
  type AxiosInstance,
  type AxiosRequestConfig,
  type AxiosResponse,
  type AxiosError,
} from "axios";
import { ElLoading } from "element-plus";
import { nextTick } from "vue";

let loadingCount = 0;
let loadingInstance: ReturnType<typeof ElLoading.service> | null = null;
type HttpMethod = "get" | "post" | "put" | "delete" | "patch";

const service: AxiosInstance = axios.create({
  baseURL: "/api",
  timeout: 5000,
});

export interface customRequestConfig extends AxiosRequestConfig {
  showLoading?: boolean;
}

export interface customAxiosResponse extends AxiosResponse {
  showLoading?: boolean;
}

const showLoading = () => {
  if (loadingCount === 0) {
    nextTick(()=>{
        loadingInstance = ElLoading.service({
            fullscreen: true,
            lock: true,
            text: 'Loading',
            background: 'rgba(0, 0, 0, 0.7)',
        });
    })
  }
  loadingCount++;
};

const hideLoading = () => {
  loadingCount--;
  if (loadingCount <= 0) {
    loadingInstance?.close();
    loadingCount = 0;
    loadingInstance = null;
  }
};

service.interceptors.request.use(
  (config: customRequestConfig) => {
    config.headers = config.headers || {};
    if (config.showLoading) {
      showLoading();
    }
    // 可在此添加类型安全的header处理
    return config;
  },
  (error: AxiosError) => {
    if (error.config?.showLoading) {
      hideLoading();
    }
    return Promise.reject(error);
  }
);

service.interceptors.response.use(
  <T = any>(res: AxiosResponse<T>) => {
    if (res.config.showLoading) {
      hideLoading();
    }
    return res.data;
  },
  (error: AxiosError) => {
    if (error.config?.showLoading) {
      hideLoading();
    }
    return Promise.reject(error);
  }
);

export function commonFetch<T = any>(
  method: HttpMethod,
  url: string,
  data?: any,
  options?: customRequestConfig
): Promise<T> {
  if (method === "get") {
    return service[method](url, {
      params: data,
      ...options,
    });
  }
  return service[method](url, data, options);
}

export function requestGet<T = any>(
  url: string,
  data?: Record<string, any>,
  options?: customRequestConfig
): Promise<T> {
  return commonFetch("get", url, data, options);
}

export function requestPost<T = any>(
  url: string,
  data?: any,
  options?: customRequestConfig
): Promise<T> {
  return commonFetch("post", url, data, options);
}

export default service;
